package com.smedi.ismedi.constructionproject.core.port.adapter.restful;

import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.smedi.ismedi.authority.starter.util.AuthorityUtil;
import com.smedi.ismedi.constructionproject.api.dto.request.*;
import com.smedi.ismedi.constructionproject.api.dto.response.ProjectApplyResponse;
import com.smedi.ismedi.constructionproject.api.dto.response.ProjectBasicResponse;
import com.smedi.ismedi.constructionproject.api.feign.RemoteProjectApplyFeignApi;
import com.smedi.ismedi.constructionproject.core.application.command.*;
import com.smedi.ismedi.constructionproject.core.application.query.ProjectApplyQueryService;
import com.smedi.ismedi.constructionproject.core.application.service.ProjectApplyApplicationService;
import com.smedi.ismedi.constructionproject.core.domain.aggregatemodel.ProjectApply;
import com.smedi.ismedi.constructionproject.core.domain.aggregatemodel.ProjectApplyListQuery;
import com.smedi.ismedi.constructionproject.core.domain.aggregatemodel.ProjectApplyPageQuery;
import com.smedi.ismedi.constructionproject.core.port.adapter.restful.convert.AdapterConverter;
import com.smedi.ismedi.organization.api.dto.response.HrOrganizationResponse;
import com.smedi.ismedi.organization.api.dto.response.ProjectOrganizationResponse;
import com.smedi.ismedi.web.starter.common.PaginationData;
import com.smedi.ismedi.web.starter.common.ResponseData;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.RestController;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @Author: xulinjun
 * @Date: 2021-6-21 10:16
 */
@Slf4j
@RestController
@AllArgsConstructor
public class ProjectApplyController implements RemoteProjectApplyFeignApi {

    private final ProjectApplyApplicationService projectApplyApplicationService;

    private final ProjectApplyQueryService projectApplyQueryService;

    private final AdapterConverter adapterConverter;

    private final ConstructionProjectController constructionProjectController;

    private final AuthorityUtil authorityUtil;

    @Override
    public ResponseData<String> getBusinessToken() {
        return new ResponseData<>().success(projectApplyApplicationService.getBusinessToken());
    }

    @Override
    public ResponseData<ProjectApplyResponse> postSave(ProjectApplyCreateRequest projectApplyCreateRequest) {
        ProjectApplyCreateCommand projectApplyCreateCommand = adapterConverter.createdRequestToCommand(projectApplyCreateRequest);


        ProjectApply projectApply = projectApplyApplicationService.postSave(projectApplyCreateCommand);

        ProjectApplyResponse projectApplyResponse = adapterConverter.projectApplyToResponse(projectApply);

        return new ResponseData<>().success(projectApplyResponse);
    }

    @Override
    public ResponseData<ProjectApplyResponse> postEdit(ProjectApplyEditRequest projectApplyEditRequest) {
        ProjectApplyEditCommand projectApplyEditCommand = adapterConverter.editRequestToCommand(projectApplyEditRequest);

        ProjectApply projectApply = projectApplyApplicationService.postEdit(projectApplyEditCommand);

        ProjectApplyResponse projectApplyResponse = adapterConverter.projectApplyToResponse(projectApply);

        return new ResponseData<>().success(projectApplyResponse);
    }

    @Override
    public ResponseData<ProjectApplyResponse> instituteLeaderApproval(ProcessInstituteLeaderApprovalRequest processInstituteLeaderApprovalRequest) {
        ProcessInstituteLeaderApprovalCommand approvalCommand = adapterConverter.instituteLeaderRequestToCommand(processInstituteLeaderApprovalRequest);

        ProjectApply projectApply = projectApplyApplicationService.instituteLeaderApproval(approvalCommand);

        ProjectApplyResponse projectApplyResponse = adapterConverter.projectApplyToResponse(projectApply);

        return new ResponseData<>().success(projectApplyResponse);
    }

    @Override
    public ResponseData<ProjectApplyResponse> engineerApproval(ProcessEngineerApprovalRequest processEngineerApprovalRequest) {
        ProcessEngineerApprovalCommand approvalCommand = adapterConverter.engineerApprovalToCommand(processEngineerApprovalRequest);

        ProjectApply projectApply = projectApplyApplicationService.engineerApproval(approvalCommand);

        ProjectApplyResponse projectApplyResponse = adapterConverter.projectApplyToResponse(projectApply);

        return new ResponseData<>().success(projectApplyResponse);
    }

    @Override
    public ResponseData<ProjectApplyResponse> engineeringLeaderApproval(ProcessEngineeringLeaderApprovalRequest processEngineeringLeaderApprovalRequest) {
        ProcessEngineeringLeaderApprovalCommand approvalCommand = adapterConverter.EngineeringLeaderRequestToCommand(processEngineeringLeaderApprovalRequest);

        ProjectApply projectApply = projectApplyApplicationService.engineeringLeaderApproval(approvalCommand);

        ProjectApplyResponse projectApplyResponse = adapterConverter.projectApplyToResponse(projectApply);

        return new ResponseData<>().success(projectApplyResponse);
    }

    @Override
    public ResponseData<ProjectApplyResponse> generalInstituteLeaderApproval(ProcessGeneralInstituteLeaderApprovalRequest processGeneralInstituteLeaderApprovalRequest) {
        ProcessGeneralInstituteLeaderApprovalCommand approvalCommand = adapterConverter.GeneralInstituteLeaderRequestToCommand(processGeneralInstituteLeaderApprovalRequest);

        ProjectApply projectApply = projectApplyApplicationService.generalInstituteLeaderApproval(approvalCommand);

        ProjectApplyResponse projectApplyResponse = adapterConverter.projectApplyToResponse(projectApply);

        return new ResponseData<>().success(projectApplyResponse);
    }

    @Override
    public ResponseData<List<ProjectApplyResponse>> getProjectApplyList(ProjectApplyListRequest projectApplyListRequest) {
        ProjectApplyListQuery projectApplyListQuery = adapterConverter.projectApplyListRequestToListQuery(projectApplyListRequest);

        List<ProjectApply> projectApplies = projectApplyQueryService.getProjectApplyList(projectApplyListQuery);
        List<ProjectApplyResponse> projectApplyResponses = adapterConverter.projectApplyListToResponseList(projectApplies);

        return new ResponseData<ProjectApplyResponse>().success(projectApplyResponses);
    }

    @Override
    public ResponseData<PaginationData<ProjectApplyResponse>> getProjectApplyPage(ProjectApplyPageRequest projectApplyPageRequest) {
        ProjectApplyPageQuery projectApplyPageQuery = adapterConverter.projectApplyPageRequestToPageQuery(projectApplyPageRequest);

        Page<ProjectApply> projectApplyPage = projectApplyQueryService.getProjectApplyPage(projectApplyPageQuery);
        PaginationData<ProjectApplyResponse> projectApplyPageToResponsePage = adapterConverter.projectApplyPageToResponsePage(projectApplyPage);

        return new ResponseData<ProjectApplyResponse>().success(projectApplyPageToResponsePage);
    }

    @Override
    public ResponseData<Boolean> restoreProject(Long projectId) {
        Boolean flag = projectApplyQueryService.restoreProject(projectId);
        return new ResponseData<Boolean>().success(flag);
    }

    @Override
    public ResponseData<Boolean> updateMonitorType() {
        Boolean flag = projectApplyApplicationService.updateMonitorType();
        return new ResponseData<Boolean>().success(flag);
    }

    @Override
    public ResponseData<ProjectApplyResponse> projectApplyDetail(Long id) {
        ProjectApply projectApply = projectApplyApplicationService.projectApplyDetail(id);

        ProjectApplyResponse projectApplyResponse = adapterConverter.projectApplyToResponse(projectApply);

        return new ResponseData<>().success(projectApplyResponse);
    }

    @Override
    public ResponseData<ProjectApplyResponse> view(Long projectId) {
        ProjectApply projectApply = projectApplyApplicationService.view(projectId);

        ProjectApplyResponse projectApplyResponse = adapterConverter.projectApplyToResponse(projectApply);

        return new ResponseData<>().success(projectApplyResponse);
    }

    @Override
    public ResponseData<List<ProjectBasicResponse>> getQueryProjectBasicListByHrOrganizationIdAndPerson(Long hrOrganizationId) {
        Set<ProjectBasicResponse> basicResponses = new HashSet<>();

        basicResponses.addAll(constructionProjectController.getQueryProjectBasicListByHrOrganizationId(hrOrganizationId).getData());
        basicResponses.addAll(constructionProjectController.getQueryProjectBasicListByPersonId(authorityUtil.getPersonId()).getData());
        if (CollectionUtils.isNotEmpty(basicResponses)) {
            List<Long> organizationIds = basicResponses.stream().map(ProjectBasicResponse::getHrOrganizationId).collect(Collectors.toList());
            Map<Long, HrOrganizationResponse> organizationResponseMap = new HashMap<>();
            List<HrOrganizationResponse> hrOrganizationResponses = projectApplyApplicationService.getOrganization(organizationIds);
            if (CollectionUtils.isNotEmpty(hrOrganizationResponses)) {
                hrOrganizationResponses.forEach(x -> organizationResponseMap.put(x.getHrOrganizationId(), x));
            }
            basicResponses.forEach(x -> {
                x.setHrOrganizationFullName(null != organizationResponseMap.get(x.getHrOrganizationId()) ?
                        organizationResponseMap.get(x.getHrOrganizationId()).getFullName() : null);
                x.setHrOrganizationShortName(null != organizationResponseMap.get(x.getHrOrganizationId()) ?
                        organizationResponseMap.get(x.getHrOrganizationId()).getShortName() : null);
            });
        }
        return new ResponseData<>().success(new ArrayList<>(basicResponses));
    }

}
